#ifndef __TRUE_MAP_LIB_H__
#define __TRUE_MAP_LIB_H__

#include <WTypes.h>

#ifndef FALSE
#define FALSE					(1 == 0)
#endif

#ifndef TRUE
#define TRUE					!(FALSE)
#endif

#ifndef TM_API
#define TM_API
#endif

#ifndef TM_API_CALLING_CONVENTION
#define TM_API_CALLING_CONVENTION __stdcall
#endif

#ifndef TM_INLINE
#define TM_INLINE				static inline
#endif

#ifdef __cplusplus
namespace TRUEMapLib
{
	extern "C"
	{
#endif // __cplusplus
		typedef void				TMVoid;
		typedef char				TMBoolean;
		typedef char				TMChar;
		typedef unsigned char		TMUChar;
		typedef short				TMShort;
		typedef unsigned short		TMUShort;
		typedef int					TMInteger;
		typedef unsigned int		TMUInteger;
		typedef long				TMLong;
		typedef unsigned long		TMULong;
		typedef float				TMFloat;
		typedef double				TMDouble;

		typedef TMVoid *			TMMapHandle;

		/** TMLocation represents geographic coordinates.*/
		typedef struct _TMLocation
		{
			/** Latitude */
			TMDouble				dLatitude;
			/** Longitude */
			TMDouble				dLongitude;
		} TMLocation;

		/** TMPoint is X, Y coordinates of screen.*/
		typedef struct _TMPoint
		{
			/** X */
			TMInteger				nX;
			/** Y */
			TMInteger				nY;
		} TMPoint;

		/** TMSize represents width and height */
		typedef struct _TMSize
		{
			/** Width */
			TMUInteger				nWidth;
			/** Height */
			TMUInteger				nHeight;
		} TMSize;

		/** TMPointRect represents a rectangle with pixel points */
		typedef struct _TMPointRect
		{
			/** Left, top vertex of the rectangle */
			TMPoint					leftTop;
			/** Right, bottom vertex of the rectangle */
			TMPoint					rightBottom;
		} TMPointRect;

		/** TMLocationRect represents a rectangle with geographic coordinates */
		typedef struct _TMLocationRect
		{
			/** Left, top vertex of the rectangle */
			TMLocation				leftTop;
			/** Right, bottom vertext of the rectangle */
			TMLocation				rightBottom;
		} TMLocationRect;

		/** Map types */
		typedef enum
		{
			/** None */
			TMMapTypeNone,
			/** Google Maps */
			TMMapTypeGoogle
		} TMMapType;

		/** Event types */
		typedef enum
		{
			/** It will be generated before map loading */
			TMEventTypeMapWillLoad,
			/** It will be generated after map loading */
			TMEventTypeMapLoaded,

			/** It will be generated before onpaint */
			TMEventTypeMapWillDraw,
			/** It will be generated after onpaint */
			TMEventTypeMapDrawn,

			/** It will be generated when mouse left button is clicked */
			TMEventTypeLButtonDown,
			TMEventTypeLButtonUp
		} TMEventType;

		TMBoolean tmInitLibrary();
		TMBoolean tmUninitLibrary();

		/** Definition of the callback function type */
		typedef TMVoid	(TM_API_CALLING_CONVENTION *PFN_TRUE_MAP_LIB_EVENT_CALLBACK)(TMMapHandle hMap, TMEventType eventType, LPARAM lParam, WPARAM wParam, TMVoid *pUserParam);

		/**
		* The Create function creates the map control. Parameters are similar with CreateWindow function of Windows API.
		* @param dwStyle Specifies the style of the window being created. This parameter can be a combination of window styles, plus the control styles indicated in the Remarks section.
		* @param rect Specifies the initial horizontal position, initial vertical position, width, height of the window. 
		* @param hParentWnd Handle to the parent or owner window. 
		* @param hInstance Handle to the instance of the module to be associated with the window. 
		* @see tmDestroy()
		* @see tmGetMapHWND()
		* @return If the function succeeds, the return value is a handle to the map control.<br>If the function fails, the return value is NULL. 
		*/
		TM_API TMMapHandle					TM_API_CALLING_CONVENTION tmCreate(DWORD dwStyle, RECT rect, HWND hParentWnd, HINSTANCE hInstance);

		/**
		* The tmDestroy function destroys the specified map control.
		* @param hMap Handle to the map control to be destroyed. 
		* @see tmCreate()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmDestroy(TMMapHandle hMap);

		/**
		* The tmLoad function loads and shows the map. The tmCreate must be called before calling this function. 
		* @param hMap Handle to the map control. 
		* @param mapType Map type to be loaded. This parameter can be a element of the TMMapType. 
		* @param center Geographic coordinates of the map center to be loaded. 
		* @param dZoomLevel Zoom level of the to be loaded map between tmGetMinZoomLevel() and tmGetMaxZoomLevel()
		* @see tmCreate()
		* @see tmGetMinZoomLevel()
		* @see tmGetMaxZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmLoad(TMMapHandle hMap, TMMapType mapType, TMLocation center, TMDouble dZoomLevel);

		/**
		* The tmGetMapHWND function returns the window handle of the map control. 
		* @param hMap Handle to the map control. 
		* @return If the function succeeds, this function returns the window handle of the map control.<br>If the function fails, the return value is NULL. 
		*/
		TM_API HWND							TM_API_CALLING_CONVENTION tmGetMapHWND(TMMapHandle hMap);

		/**
		* The tmSetMapType function changes the map type.
		* @param hMap Handle to the map control. 
		* @param mapType Map type to be loaded. This parameter can be a element of the TMMapType. 
		* @see tmGetMapType()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmSetMapType(TMMapHandle hMap, TMMapType mapType);

		/**
		* The tmGetMapType function retrieves the current set map type.
		* @param hMap Handle to the map control. 
		* @see tmSetMapType()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMMapType					TM_API_CALLING_CONVENTION tmGetMapType(TMMapHandle hMap);

		/**
		* The tmSetMapCenterLocationWithZoomLevel function changes the map center coordinates to the inputed coordinates and changes zoom level.  
		* @param hMap Handle to the map control. 
		* @param center The geographic coordinates to be moved location.
		* @param dZoomLevel Zoom level of the to be loaded map between tmGetMinZoomLevel() and tmGetMaxZoomLevel().
		* @see tmSetMapCenterLocation()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmSetMapCenterLocationWithZoomLevel(TMMapHandle hMap, TMLocation center, TMDouble dZoomLevel);

		/**
		* The tmSetMapCenterLocation function changes the map center coordinates to the inputed coordinates.
		* @param hMap Handle to the map control. 
		* @param center The geographic coordinates to be moved location.
		* @see tmSetMapCenterLocationWithZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmSetMapCenterLocation(TMMapHandle hMap, TMLocation center);

		/**
		* The tmMoveCenterPointWithZoomLevel function moves the map to inputed x, y pixels and changes zoom level.
		* @param hMap Handle to the map control. 
		* @param delta X, Y pixels to be moved.
		* @param dZoomLevel Zoom level of the to be loaded map between tmGetMinZoomLevel() and tmGetMaxZoomLevel().
		* @see tmMoveCenterPoint()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmMoveCenterPointWithZoomLevel(TMMapHandle hMap, TMPoint delta, TMDouble dZoomLevel);

		/**
		* The tmMoveCenterPoint function moves the map to inputed x, y pixels.
		* @param hMap Handle to the map control. 
		* @param delta X, Y pixels to be moved.
		* @see tmMoveCenterPoint()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmMoveCenterPoint(TMMapHandle hMap, TMPoint delta);

		/**
		* The tmSetZoomLevel function changes the current zoom level. 
		* @param hMap Handle to the map control. 
		* @param dZoomLevel The zoom level to be changed.
		* @see tmGetZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmSetZoomLevel(TMMapHandle hMap, TMDouble dZoomLevel);

		/**
		* The tmSetZoomLevel function retrieves the current zoom level. 
		* @param hMap Handle to the map control. 
		* @see tmGetZoomLevel()
		* @return If the function succeeds, the return value is set current zoom level.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMDouble						TM_API_CALLING_CONVENTION tmGetZoomLevel(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function increases by 1 point the current zoom level. 
		* @param hMap Handle to the map control. 
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmZoomIn(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function decreases by 1 point the current zoom level. 
		* @param hMap Handle to the map control. 
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmZoomOut(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function determines whether the specified number is the maximum zoom level of current map. 
		* @param hMap Handle to the map control. 
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmIsMaxZoom(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function determines whether the specified number is the minimum zoom level of current map. 
		* @param hMap Handle to the map control. 
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is TRUE.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmIsMinZoom(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function returns the maximum zoom level. 
		* @param hMap Handle to the map control. 
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is maximum zoom level.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMDouble						TM_API_CALLING_CONVENTION tmGetMaxZoomLevel(TMMapHandle hMap);

		/**
		* The tmSetZoomLevel function returns the minimum zoom level. 
		* @param hMap Handle to the map control.
		* @see tmSetZoomLevel()
		* @see tmGetZoomLevel()
		* @see tmZoomIn()
		* @see tmZoomOut()
		* @see tmIsMaxZoom()
		* @see tmIsMinZoom()
		* @see tmGetMaxZoomLevel()
		* @see tmGetMinZoomLevel()
		* @return If the function succeeds, the return value is minimum zoom level.<br>If the function fails, the return value is FALSE. 
		*/
		TM_API TMDouble						TM_API_CALLING_CONVENTION tmGetMinZoomLevel(TMMapHandle hMap);

		/**
		* The tmGetMeterFromPixelWidth function convert pixel of width into distance(meters) on specified zoom level.
		* @param hMap Handle to the map control. 
		* @param dMapLevel Specified zoom level.
		* @param nPixelWidth Number of pixels to be converted.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is meter distance. <br>If the function fails the return value is -1. 
		*/
		TM_API TMDouble						TM_API_CALLING_CONVENTION tmGetMeterFromPixelWidth(TMMapHandle hMap, TMDouble dMapLevel, TMInteger nPixelWidth);

		/**
		* The tmGetMeterFromPixelWidth function convert pixel of height into distance(meters) on specified zoom level.
		* @param hMap Handle to the map control. 
		* @param dMapLevel Specified zoom level.
		* @param nPixelHeight Number of pixels to be converted.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is meter distance.<br>If the function fails, the return value is -1. 
		*/
		TM_API TMDouble						TM_API_CALLING_CONVENTION tmGetMeterFromPixelHeight(TMMapHandle hMap, TMDouble dMapLevel, TMInteger nPixelHeight);

		/**
		* The tmGetScreenPointFromLocation function convert geographic coordinates into screen point.
		* @param hMap Handle to the map control. 
		* @param location Geographic coordinates to be converted.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is TMPoint represented by screen point.
		*/
		TM_API TMPoint						TM_API_CALLING_CONVENTION tmGetScreenPointFromLocation(TMMapHandle hMap, TMLocation location);

		/**
		* The tmGetLocationFromScreenPoint function converts screen point into geographic coordinates on specified zoom level.
		* @param hMap Handle to the map control.
		* @param point Screen point to be converted.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is TMLocation represented by geographic coordinates.
		*/
		TM_API TMLocation					TM_API_CALLING_CONVENTION tmGetLocationFromScreenPoint(TMMapHandle hMap, TMPoint point);

		/**
		* The tmGetLocationFromScreenCenter function retrieves the geographic coordinates on the center of current screen.
		* @param hMap Handle to the map control.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is TMLocation represented by geographic coordinates.
		*/
		TM_API TMLocation					TM_API_CALLING_CONVENTION tmGetLocationFromScreenCenter(TMMapHandle hMap);

		/**
		* The tmGetLocationScreenRect function retrieves the geographic coordinates dimensions of the bounding rectangle of the screen.
		* @param hMap Handle to the map control.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is TMLocationRect represented by geographic coordinates dimensions.
		*/
		TM_API TMLocationRect				TM_API_CALLING_CONVENTION tmGetLocationScreenRect(TMMapHandle hMap);

		/**
		* The GetMovedPoint function retrieves the moved point.
		* @param hMap Handle to the map control.
		* @see tmGetMeterFromPixelWidth()
		* @see tmGetMeterFromPixelHeight()
		* @see tmGetScreenPointFromLocation()
		* @see tmGetLocationFromScreenPoint()
		* @see tmGetLocationFromScreenCenter()
		* @see tmGetLocationScreenRect()
		* @return If the function succeeds, the return value is TMPoint.
		*/
		TM_API TMPoint						TM_API_CALLING_CONVENTION tmGetMovedPoint(TMMapHandle hMap);

		/**
		* The tmInvalidate function redraws map.
		* @return If the function succeeds, the return value is TRUE
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmInvalidate(TMMapHandle hMap);

		/**
		* The tmRegisterEventCallback function registers a callback function which called when generates event among TMEventType. 
		* @param hMap Handle to the map control.
		* @param pfnTarget Callback function.
		* @param pUserParam A pointer to a variable to be passed to the callback function.
		* @return If the function succeeds, the return value is TRUE. <br>If the function fails, the return value is FALSE;
		*/
		TM_API TMBoolean					TM_API_CALLING_CONVENTION tmRegisterEventCallback(TMMapHandle hMap, PFN_TRUE_MAP_LIB_EVENT_CALLBACK pfnTarget, TMVoid *pUserParam);

#ifdef __cplusplus
	} // extern "C"
} // namespace TRUEMapLib
#endif // __cplusplus

#endif // __TRUE_MAP_LIB_H__
